package com.wego.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.wego.bean.PageBean;
import com.wego.converter.CommentConverter;
import com.wego.domain.entity.Comment;
import com.wego.domain.entity.User;
import com.wego.domain.entity.UserLikeRelation;
import com.wego.domain.query.CommentQuery;
import com.wego.domain.query.UserLikeRelationQuery;
import com.wego.domain.vo.CommentVO;
import com.wego.mapper.CommentMapper;
import com.wego.mapper.UserLikeRelationMapper;
import com.wego.mapper.UserMapper;
import com.wego.service.CommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class CommentServiceImpl implements CommentService {
    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserLikeRelationMapper userLikeRelationMapper;
    @Autowired
    private CommentConverter commentConverter;

    @Override
    public PageBean<CommentVO> getPage(CommentQuery commentQuery) {
        final Integer pageNum = commentQuery.getPageNum();
        final Integer pageSize = commentQuery.getPageSize();
        final Page<CommentVO> page = PageHelper.startPage(pageNum, pageSize);
        commentMapper.selectWithConditionWithoutPid(commentQuery);
        return PageBean.page2pageBean(page);
    }

    @Override
    public CommentVO getById(Integer id) {
        return commentMapper.selectCommentVOByPrimaryKey(id);
    }

    @Override
    public int insert(Comment comment) {
        if (comment == null) {
            throw new IllegalArgumentException("Comment cannot be null");
        }
        if (comment.getContent() == null) {
            throw new IllegalArgumentException("Content cannot be null");
        }
        if (comment.getUserId() == null) {
            throw new IllegalArgumentException("User ID cannot be null");
        }
        if (comment.getStrategyId() == null) {
            throw new IllegalArgumentException("Strategy ID cannot be null");
        }
        if(comment.getLikeCount() == null) {
            comment.setLikeCount(0);
        }
        //设置更新时间为当前时间
        comment.setCreateTime(LocalDateTime.now());
        comment.setUpdateTime(LocalDateTime.now());
        return commentMapper.insertSelective(comment);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteByIds(List<Integer> ids) {
        return commentMapper.deleteByPrimaryKeyIn(ids);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
    public int batchInsert(List<Comment> commentList) {
        return commentMapper.batchInsert(commentList);
    }

    /**
     * 填充CommentVO列表中的用户信息和创建时间
     * @param commentVOList 评论VO列表
     * @param currentUserId 当前用户ID，用于判断是否点赞
     */
    private void fillCommentVOs(List<CommentVO> commentVOList, Integer currentUserId) {
        // 收集所有需要查询的用户ID
        List<Integer> userIds = commentVOList.stream()
                .map(CommentVO::getUserId)
                .filter(userId -> userId != null)
                .distinct()
                .collect(Collectors.toList());

        // 批量查询用户信息
        Map<Integer, User> userMap = userIds.stream()
                .collect(Collectors.toMap(
                        userId -> userId,
                        userId -> {
                            User user = userMapper.selectByPrimaryKey(userId);
                            return user != null ? user : new User(); // 返回空User对象而不是null
                        }
                ));

        // 如果当前用户ID不为空，检查点赞状态
        if (currentUserId != null) {
            // 收集所有评论ID
            List<Integer> commentIds = commentVOList.stream()
                    .map(CommentVO::getId)
                    .filter(id -> id != null)
                    .collect(Collectors.toList());

            if (!commentIds.isEmpty()) {
                // 查询当前用户对这些评论的点赞情况
                UserLikeRelationQuery likeQuery = new UserLikeRelationQuery();
                likeQuery.setUserId(currentUserId);
                likeQuery.setEntityType(1); // 评论类型
                likeQuery.setEntityIdIn(commentIds);
                
                List<UserLikeRelation> likeRelations = userLikeRelationMapper.selectWithCondition(likeQuery);
                Map<Integer, Boolean> likeMap = likeRelations.stream()
                        .collect(Collectors.toMap(
                                UserLikeRelation::getEntityId,
                                relation -> true
                        ));

                // 设置点赞状态
                for (CommentVO commentVO : commentVOList) {
                    commentVO.setIsLiked(likeMap.getOrDefault(commentVO.getId(), false));
                }
            }
        }

        for (CommentVO commentVO : commentVOList) {
            // 填充用户信息（头像和名字）
            if (commentVO.getUserId() != null) {
                User user = userMap.get(commentVO.getUserId());
                if (user != null) {
                    commentVO.setUserName(user.getNickname());
                    commentVO.setUserAvatar(user.getAvatar());
                }
            }
            
            // 创建时间已经在CommentVO中以字符串形式存在，无需额外处理
        }
    }

    // 重载方法，不处理点赞状态
    private void fillCommentVOs(List<CommentVO> commentVOList) {
        fillCommentVOs(commentVOList, null);
    }

    @Override
    public List<CommentVO> getCommentWithSub(Integer parentCount, Integer subCount) {
        //1、从表中读取出前n个顶级类别（pid=null）
        CommentQuery commentQuery0 = new CommentQuery();
        commentQuery0.setParentId(null);
        commentQuery0.setPageSize(parentCount);
        final List<CommentVO> res = commentMapper.selectCommentByPid(commentQuery0);

        // 填充用户信息和创建时间
        fillCommentVOs(res);

        //2、从每个顶级类别中读取出前m个子类别
        for (CommentVO comment : res) {
            CommentQuery commentQuery1 = new CommentQuery();
            commentQuery1.setParentId(comment.getId());
            commentQuery1.setPageSize(subCount);
            final List<CommentVO> tmp = commentMapper.selectCommentByPid(commentQuery1);
            // 填充子评论的用户信息和创建时间
            fillCommentVOs(tmp);
            comment.setSub(tmp);
        }

        return res;
    }

    @Override
    public PageBean<CommentVO> getCommentWithSubPage(CommentQuery commentQuery) {
        System.out.println("commentQueryService:" + commentQuery);
        // 1、分页查询顶级评论（parentId=null）
        Integer currentUserId = commentQuery.getUserId();
        commentQuery.setUserId(null);
        commentQuery.setParentId(null);
        Page<Comment> page = PageHelper.startPage(commentQuery.getPageNum(), commentQuery.getPageSize());
        commentMapper.selectWithCondition(commentQuery);

        // 转换为VO对象
        List<CommentVO> commentVOList = commentConverter.commentList2CommentVOList(page.getResult());
        // 填充用户信息和创建时间，并处理点赞状态（如果提供了用户ID）
        fillCommentVOs(commentVOList, currentUserId);

        // 2、为每个顶级评论查询其子评论
        for (CommentVO commentVO : commentVOList) {
            CommentQuery subCommentQuery = new CommentQuery();
            subCommentQuery.setParentId(commentVO.getId());
            // 子评论暂时不分页，获取所有子评论
            List<CommentVO> subCommentVOs = commentMapper.selectCommentByPid(subCommentQuery);
            // 填充子评论的用户信息和创建时间
            fillCommentVOs(subCommentVOs, currentUserId);
            commentVO.setSub(subCommentVOs);
        }

        // 构造返回的PageBean
        PageBean<CommentVO> pageBean = new PageBean<>();
        pageBean.setRecords(commentVOList);
        pageBean.setTotal(page.getTotal());
        pageBean.setPageNum(page.getPageNum());
        pageBean.setPageSize(page.getPageSize());
        pageBean.setPages(page.getPages());
        
        return pageBean;
    }

    @Override
    public int update(Comment comment) {
        if (comment == null) {
            throw new IllegalArgumentException("Comment cannot be null");
        }
        if (comment.getId() == null) {
            throw new IllegalArgumentException("ID cannot be null");
        }
        return commentMapper.updateByPrimaryKeySelective(comment);

    }
}